﻿using ArtMath.Core.Data;
using ArtMath.Data;
using ArtMath.Attribute;
using System.Drawing;
using System.ComponentModel;
using ArtMath.Resource;
using System;
using ArtMath.Component.CoordinateSystem;

namespace ArtMath.Component.Point
{
    /// <summary>
    /// 极坐标系点基类
    /// </summary>
    [Serializable]
    public abstract class PPointBase : PointBase
    {
        PadStringX rou, theta;
        public PPointBase(SketchPad pad, string name, ToolTypeName toolType, bool addToList = false) : base(pad, name, toolType, addToList)
        {
            ρ = new PadStringX(Pad);
            θ = new PadStringX(Pad);
            CoordinateDisplayer = new PropertyDisplayer(this, Resources.Translate("Coordinate"), "({0}, {1})", "ρ", "θ");
        }
        [MultilingualCategory("Parameter"), ReadOnly(true)]
        public override PadStringX X
        {
            get
            {
                return base.X;
            }

            set
            {
                base.X = value;
            }
        }
        [MultilingualCategory("Parameter"), ReadOnly(true)]
        public override PadStringX Y
        {
            get
            {
                return base.Y;
            }

            set
            {
                base.Y = value;
            }
        }
        [MultilingualCategory("Structure")]
        public virtual PadStringX ρ
        {
            get { return rou; }
            set
            {
                if (rou is object)
                {
                    rou.ParametersValueChanging -= RT_ParametersValueChanging;
                    rou.ParametersValueChanged -= RT_ParametersValueChanged;
                    rou.ExpressionSet -= RT_ExpressionSet;
                    rou.ExpressionSetting -= RT_ExpressionSetting;
                }
                rou = value;
                if (rou is object)
                {
                    rou.ParametersValueChanging += RT_ParametersValueChanging;
                    rou.ParametersValueChanged += RT_ParametersValueChanged;
                    rou.ExpressionSet += RT_ExpressionSet;
                    rou.ExpressionSetting += RT_ExpressionSetting;
                }
            }
        }
        [MultilingualCategory("Structure")]
        public virtual PadStringX θ
        {
            get { return theta; }
            set
            {
                if (theta is object)
                {
                    theta.ParametersValueChanging -= RT_ParametersValueChanging;
                    theta.ParametersValueChanged -= RT_ParametersValueChanged;
                    theta.ExpressionSet -= RT_ExpressionSet;
                    theta.ExpressionSetting -= RT_ExpressionSetting;
                }
                theta = value;
                if (theta is object)
                {
                    theta.ParametersValueChanging += RT_ParametersValueChanging;
                    theta.ParametersValueChanged += RT_ParametersValueChanged;
                    theta.ExpressionSet += RT_ExpressionSet;
                    theta.ExpressionSetting += RT_ExpressionSetting;
                }
            }
        }
        void RT_ExpressionSetting(StringX sender)
        {
            Pad.MoveObject_DoMouseDown(this);
        }

        void RT_ParametersValueChanging(DocStringX sender)
        {
            Pad.MoveObject_DoMouseDown(this);
        }

        void RT_ExpressionSet(StringX sender, ExpressionSetEventArgs e)
        {
            PolarCoordinate pc = Pad.Coordinate as PolarCoordinate;
            if (pc != null)
            {
                if (Pad.MoveObject_DoMouseMove(this, pc.RTtoPxy(ToPPointD())))
                {

                }
                else
                {
                    Pad.ShowMessage(string.Format(Resources.Translate("FailedModify"), Resources.Translate("Coordinate")), MessageType.Exclamation);
                    sender.SetExpression(e.OldExpression, false);
                }
            }
            Pad.MoveObject_DoMouseUp(this);
        }
        void RT_ParametersValueChanged(DocStringX sender, ParametersValueChangedEventArgs e)
        {
            PolarCoordinate pc = Pad.Coordinate as PolarCoordinate;
            if (pc != null)
            {
                if (Pad.MoveObject_DoMouseMove(this, pc.RTtoPxy(ToPPointD())))
                {

                }
            }
            Pad.MoveObject_DoMouseUp(this);
        }
        public override bool CoordinateExpressionContainParameter
        {
            get
            {
                return ρ.ContainsParameter || θ.ContainsParameter;
            }
        }
        public PointD ToPPointD()
        {
            return new PointD(rou.Value, theta.Value);
        }
        public override PointD ToMathCoordinate()
        {
            return ToPPointD();
        }
        public PointF ToPPointF()
        {
            return new PointF(rou.FloatValue, theta.FloatValue);
        }
        public override string ToString()
        {
            return rou.ToString() + ", " + theta.ToString();
        }
    }
}
